﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Nancy;
using Nancy.Cookies;
using QQ2564874169.Core.Utils;
using QQ2564874169.WebFx.Nancy.Utils;
using QQ2564874169.WebFx.Nancy.Web;
using Website.App;
using Website.Models;

namespace Website.Apis
{
    public class Api : Controller
    {
        private static List<Game> _games = new List<Game>();
        private const string PID = "pid";
        private long? Pid
        {
            get
            {
                if (Request.Cookies.ContainsKey(PID))
                    return long.Parse(Request.Cookies[PID]);
                return null;
            }
        }

        static Api()
        {
            new Thread(() =>
            {
                while (true)
                {
                    Thread.Sleep(1000*60*5);

                    lock (_games)
                    {
                        foreach (var game in _games.ToArray())
                        {
                            if (game.Players.All(i => i.LogTime.AddMinutes(5) < DateTime.Now))
                            {
                                _games.Remove(game);
                            }
                        }
                    }
                }
            }) {IsBackground = true}.Start();
        }

        [Get("/")]
        public object Home()
        {
            return GetView("/home", _games.Select(i => new HomeVo
            {
                Id = i.Id,
                Name = i.Name,
                Count = i.Players.Count,
                Started = i.Started,
                StartTime = i.StartTime
            }).ToArray());
        }

        [Post("/newgame")]
        public object NewGame()
        {
            var name = Request.Params("name");
            if (string.IsNullOrEmpty(name))
                throw new Exception("玩家必须有名字。");
            var gname = Request.Params("gname");
            if (string.IsNullOrEmpty(gname))
                throw new Exception("游戏必须有名字。");
            var game = new Game
            {
                Name = gname
            };
            var newp = new Player
            {
                Name = name,
                Id = GenerateId.New(),
                LogTime = DateTime.Now
            };
            game.AddPlayer(newp);
            _games.Add(game);
            var resp = Response.AsText(game.Id.ToString());
            resp.Cookies.Add(new NancyCookie(PID, newp.Id.ToString()));
            return resp;
        }

        [Post("/togame")]
        public object GoToGame()
        {
            var name = Request.Params("name");
            if (string.IsNullOrEmpty(name))
                throw new Exception("必须有名字。");
            var gid = new Guid(Request.Params("gid"));
            var game = _games.First(i => i.Id == gid);
            long pidv;
            if (game.Players.Any(i => i.Name == name))
            {
                pidv = game.RestorePlayer(name);
            }
            else
            {
                var newp = new Player
                {
                    Name = name,
                    Id = GenerateId.New()
                };
                game.AddPlayer(newp);
                pidv = newp.Id;
            }
            var resp = Response.AsText(game.Id.ToString());
            resp.Cookies.Add(new NancyCookie(PID, pidv.ToString()));
            return resp;
        }

        [Get("/game/{gid}")]
        public object Game()
        {
            if (Pid.HasValue == false)
                throw new Exception("未创建玩家信息。");
            return GetView("/game", new GameVo
            {
                Pid = Pid.Value,
                Gid = Guid.Parse(RouteParam("gid"))
            });
        }

        [Get("/gaming")]
        public object Gaming()
        {
            if (Pid.HasValue == false)
                throw new Exception("未创建玩家信息。");
            var p = GetGame().GetPlayer(Pid.Value);
            return p.GetCommandJson();
        }

        [Post("/ready")]
        public object Ready()
        {
            if (Pid.HasValue == false)
                throw new Exception("未创建玩家信息。");
            GetGame().Ready(Pid.Value);
            return "ok";
        }

        [Post("/chupai")]
        public object Chupai()
        {
            if (Pid.HasValue == false)
                throw new Exception("未创建玩家信息。");
            var val = Request.Params("pais");
            var items = val.Split(',');
            var pais = items.Select(int.Parse).ToArray();
            GetGame().ChuPai(Pid.Value, pais);
            return "ok";
        }

        [Post("/pass")]
        public object Pass()
        {
            if (Pid.HasValue == false)
                throw new Exception("未创建玩家信息。");
            GetGame().Pass(Pid.Value);
            return "ok";
        }

        private Game GetGame()
        {
            var strgid = Request.Params("gid");
            if (string.IsNullOrEmpty(strgid))
                throw new Exception("缺少gid。");
            var gid = Guid.Parse(strgid);
            return _games.First(i => i.Id == gid);
        }
    }
}